package com.study.common.swagger.util;

import org.springframework.util.StringUtils;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author Ming
 * @description
 * @fileSimpleName StringUtil
 * @fileName com.common.util.StringUtil
 * @date 2022年03月10日 17:10
 */
public abstract class StringUtil {

    public static final String BLANK = "";
    public final static String COMMA = ",";
    /**
     * 下划线
     */
    private static final char SEPARATOR = '_';
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^([a-z0-9A-Z]+[-|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$");

    private static final Pattern PHONE_PATTERN = Pattern.compile("^\\+{0,1}\\d{0,5} {0,1}\\d{4,}$");

    public static String joining(String[] format, Object... arguments) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < format.length; i++) {
            if (format[i] != null) {
                sb.append(format[i]);
            }
            if (i < arguments.length && arguments[i] != null) {
                sb.append(arguments[i]);
            }
        }
        return sb.toString();
    }

    public static String joining(String name, Object... arguments) {
        if (arguments.length == 0) {
            return name;
        }
        StringBuilder sb = new StringBuilder(name);
        sb.append("[");
        sb.append(arguments[0]);
        sb.append(",");
        for (int i = 1; i < arguments.length; i++) {
            sb.append(",");
            sb.append(arguments[i]);
        }
        sb.append("]");
        return sb.toString();
    }

    public static String trimLimitLen(String content, int limit) {
        if (isEmpty(content)) {
            return "";
        }
        content = content.trim();
        if (content.length() <= limit) {
            return content;
        }
        return content.substring(0, limit);
    }

    public static boolean isNotEmpty(String... args) {
        for (String string : args) {
            if (string == null || string.isEmpty()) {
                return false;
            }
        }
        return true;
    }

    public static boolean isEmpty(String... args) {
        return !isNotEmpty(args);
    }

    /**
     * 转义特殊字符 <转成&lt; >转成&gt; '转成&#039; "转成&quot;
     *
     * @param source
     * @return
     */
    public static String encode(String source) {
        if (isEmpty(source)) {
            return source;
        }
        return source.replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll("'", "&#039;").replaceAll("\"", "&quot;");
    }

    /**
     * 转义特殊字符 &lt;转成< &gt;转成> &#039;转成' &quot;转成"
     *
     * @param source
     * @return
     */
    public static String decode(String source) {
        if (isEmpty(source)) {
            return source;
        }
        return source.replaceAll("&lt;", "<").replaceAll("&gt;", ">").replaceAll("&#039;", "'").replaceAll("&quot;", "\"");
    }

    /**
     * 验证是否是邮箱
     *
     * @param string
     * @return
     */
    public static boolean isEmail(String string) {
        if (isEmpty(string)) {
            return false;
        }
        if (EMAIL_PATTERN.matcher(string.trim()).matches()) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 验证待国际区号或者不带国际去好的电话或者手机号
     * +86 12312412412444
     * +8612312412412444
     * 12312412412444
     *
     * @param string
     * @return
     */
    public static boolean isPhone(String string) {
        if (isEmpty(string)) {
            return false;
        }
        if (PHONE_PATTERN.matcher(string.trim()).matches()) {
            return true;
        } else {
            return false;
        }
    }


    /**
     * 集合转字符串
     *
     * @param list
     * @param spilt 分隔符
     * @return
     */
    public static String join(List<?> list, String spilt) {
        StringBuffer s = new StringBuffer("");
        for (int i = 0; i < list.size(); i++) {
            if (i == 0) {
                s.append(list.get(i));
            } else {
                s.append(spilt);
                s.append(list.get(i));
            }
        }
        return s.toString();
    }


    private static String changeCharSet(
            String str, String newCharset) throws UnsupportedEncodingException {
        if (str != null) {
            // 用默认字符编码解码字符串。
            byte[] bs = str.getBytes();
            // 用新的字符编码生成字符串
            return new String(bs, newCharset);
        }
        return str;
    }

    /**
     * 字符串转化为UTF-8
     *
     * @param str
     * @return
     */
    public static String toUTF8(String str) {
        String result = str;
        try {
            result = changeCharSet(str, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * 字节数组转化为UTF-8
     *
     * @param bty
     * @return
     */
    public static String toUTF8(byte[] bty) {
        try {
            if (bty.length > 0) {
                return new String(bty, "UTF-8");
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return new String(bty);
    }

    /**
     * 下划线转驼峰命名
     */
    public static String toUnderScoreCase(String str) {
        if (str == null) {
            return null;
        }
        StringBuilder sb = new StringBuilder();
        // 前置字符是否大写
        boolean preCharIsUpperCase = true;
        // 当前字符是否大写
        boolean curreCharIsUpperCase = true;
        // 下一字符是否大写
        boolean nexteCharIsUpperCase = true;
        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (i > 0) {
                preCharIsUpperCase = Character.isUpperCase(str.charAt(i - 1));
            } else {
                preCharIsUpperCase = false;
            }

            curreCharIsUpperCase = Character.isUpperCase(c);

            if (i < (str.length() - 1)) {
                nexteCharIsUpperCase = Character.isUpperCase(str.charAt(i + 1));
            }

            if (preCharIsUpperCase && curreCharIsUpperCase && !nexteCharIsUpperCase) {
                sb.append(SEPARATOR);
            } else if ((i != 0 && !preCharIsUpperCase) && curreCharIsUpperCase) {
                sb.append(SEPARATOR);
            }
            sb.append(Character.toLowerCase(c));
        }

        return sb.toString();
    }

    /**
     * * 判断一个对象是否为空
     *
     * @param object Object
     * @return true：为空 false：非空
     */
    public static boolean isNull(Object object) {
        return object == null;
    }

    /**
     * * 判断一个对象是否非空
     *
     * @param object Object
     * @return true：非空 false：空
     */
    public static boolean isNotNull(Object object) {
        return !isNull(object);
    }

    /**
     * * 判断一个对象数组是否为空
     *
     * @param objects 要判断的对象数组
     *                * @return true：为空 false：非空
     */
    public static boolean isEmpty(Object[] objects) {
        return isNull(objects) || (objects.length == 0);
    }

    /**
     * 格式化文本, {} 表示占位符<br>
     * 此方法只是简单将占位符 {} 按照顺序替换为参数<br>
     * 如果想输出 {} 使用 \\转义 { 即可，如果想输出 {} 之前的 \ 使用双转义符 \\\\ 即可<br>
     * 例：<br>
     * 通常使用：format("this is {} for {}", "a", "b") -> this is a for b<br>
     * 转义{}： format("this is \\{} for {}", "a", "b") -> this is \{} for a<br>
     * 转义\： format("this is \\\\{} for {}", "a", "b") -> this is \a for b<br>
     *
     * @param template 文本模板，被替换的部分用 {} 表示
     * @param params   参数值
     * @return 格式化后的文本
     */
    public static String format(String template, Object... params) {
        if (isEmpty(params) || isEmpty(template)) {
            return template;
        }
        return StrFormatter.format(template, params);
    }

    /**
     * 是否包含字符串
     *
     * @param str  验证字符串
     * @param strs 字符串组
     * @return 包含返回true
     */
    public static boolean inStringIgnoreCase(String str, String... strs) {
        if (str != null && strs != null) {
            for (String s : strs) {
                if (str.equalsIgnoreCase(trim(s))) {
                    return true;
                }
            }
        }
        return false;
    }

    /**
     * 去空格
     */
    public static String trim(String str) {
        return (str == null ? "" : str.trim());
    }

    public static String defaultIfEmpty(String str, String defaultStr) {
        return isEmpty(str) ? defaultStr : str;
    }

    /**
     * 将List转换为字符串
     *
     * @param array
     * @param split      分隔符
     * @param conjSymbol 连接符
     * @return 例：List元素【1，2，3】 split为"-" conjSymbol为"'" 输出为'1'-'2'-'3'
     * 例：List元素【1，2，3】 split为"," conjSymbol为"" 输出为1,2,3
     */
    public static String changeListToString(String[] array, String split, String conjSymbol) {
        if (array != null && array.length > 0) {
            return changeListToString(Arrays.asList(array), split, conjSymbol);
        }
        return null;
    }

    /**
     * 将List转换为字符串
     *
     * @param list
     * @param split      分隔符
     * @param conjSymbol 连接符
     * @return 例：List元素【1，2，3】 split为"-" conjSymbol为"'" 输出为'1'-'2'-'3'
     * 例：List元素【1，2，3】 split为"," conjSymbol为"" 输出为1,2,3
     */
    public static String changeListToString(List<?> list, String split, String conjSymbol) {
        StringBuffer target = null;
        if (list != null && !list.isEmpty()) {
            split = (split == null ? "" : split);
            conjSymbol = (conjSymbol == null ? "" : conjSymbol);
            for (Object string : list) {
                String temp = conjSymbol + string.toString() + conjSymbol;
                if (target == null) {
                    target = new StringBuffer(temp);
                } else {
                    //tempTarget = ,1,2,3,....
                    String tempTarget = split + target.toString() + split;
                    //tempString = ,2,
                    String tempString = split + string.toString() + split;
                    //比较元素是否重复
                    if (!tempTarget.contains(tempString)) {
                        target.append(split).append(temp);
                    }
                }
            }
            return target.toString();
        }
        return null;
    }

    /**
     * 转换字符串List集合
     *
     * @param inString 在弦
     * @param split    分裂
     * @return {@link List<String>}
     */
    public static List<String> conversionStringToList(String inString, String split) {
        List<String> outStringList = new ArrayList<String>();
        if (StringUtil.isNotEmpty(inString)) {
            split = (split == null ? "," : split);
            if (inString.indexOf(split) >= 0 || "\\+".equals(split)) {
                for (String app : inString.split(split)) {
                    outStringList.add(app.replaceAll("'", ""));
                }
            } else {
                outStringList.add(inString.replaceAll("'", ""));
            }
        }
        return outStringList;
    }

    /**
     * 判断Integer不为空并且大于0
     *
     * @param t
     * @return
     */
    public static boolean notEmpty(Integer t) {
        return t != null && t > 0;
    }

    /**
     * 判断是否是整数或者是小数
     *
     * @param str
     * @return true：是，false不是
     */
    public static boolean validateNumber(String str) {
        if (StringUtils.isEmpty(str)) {
            return false;
        }
        return str.matches("[+-]?[0-9]+(\\.[0-9]+)?");
    }

    /**
     * 清除字符串的小数点
     *
     * @param str
     * @return
     */
    public static String clearStrDecimal(String str) {
        if (StringUtils.isEmpty(str)) {
            return null;
        }
        BigDecimal value = new BigDecimal(str);
        BigDecimal noZeros = value.stripTrailingZeros();
        return noZeros.toPlainString();
    }

    /**
     * 字符串转小写
     *
     * @param str
     * @return
     */
    public static String lowerCase(String str) {
        return str == null ? null : str.toLowerCase();
    }

    public static String connect(Object[] objs, String link, String surround) {
        return connect(objs, link, surround, false);
    }

    public static String connect(Object[] objs, String link, String surround, boolean hasBlank) {
        if (link == null) {
            link = COMMA;
        }
        if (objs != null && objs.length > 0) {
            StringBuilder sb = new StringBuilder();
            for (Object s : objs) {
                if (sb.length() > 0) {
                    sb.append(link);
                }
                sb.append(getSurrounded(s, surround));
            }
            return sb.toString();
        }
        return hasBlank ? getSurrounded(null, surround) : BLANK;
    }

    private static String getSurrounded(Object v, String surround) {
        boolean needSrd = surround != null;
        StringBuilder sb = new StringBuilder();
        if (needSrd) {
            sb.append(surround);
        }
        if (v != null) {
            sb.append(v);
        }
        if (needSrd) {
            sb.append(surround);
        }
        return sb.toString();
    }
}
